package com.aliyun.tiangong.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.aliyun.tiangong.config.properties.DruidProperties;
import com.aliyun.tiangong.config.properties.TiangongProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Objects;

/**
 * @author xinghen
 * @ClassName: DruidConfiguration
 * @Package: com.aliyun.config
 * @Description druid配置
 * @create 2018/04/19 20:39
 */
@Slf4j
@Configuration
public class DruidConfiguration {

    @Autowired
    private TiangongProperties tiangongProperties;

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        DruidProperties druidProperties = tiangongProperties.getDruid();
        //基础配置
        dataSource.setDriverClassName(druidProperties.getDriverClassName());
        dataSource.setUrl(druidProperties.getUrl());
        dataSource.setUsername(druidProperties.getUsername());
        dataSource.setPassword(druidProperties.getPassword());
        //可选配置
        if (Objects.nonNull(druidProperties.getInitialSize())) {
            dataSource.setInitialSize(druidProperties.getInitialSize());
        }
        if (Objects.nonNull(druidProperties.getMaxActive())) {
            dataSource.setMaxActive(druidProperties.getMaxActive());
        }
        if (Objects.nonNull(druidProperties.getMaxWait())) {
            dataSource.setMaxWait(druidProperties.getMaxWait());
        }
        if (Objects.nonNull(druidProperties.getTimeBetweenEvictionRunsMillis())) {
            dataSource.setTimeBetweenEvictionRunsMillis(druidProperties.getTimeBetweenEvictionRunsMillis());
        }
        if (Objects.nonNull(druidProperties.getMinEvictableIdleTimeMillis())) {
            dataSource.setMinEvictableIdleTimeMillis(druidProperties.getMinEvictableIdleTimeMillis());
        }
        if (Objects.nonNull(druidProperties.getValidationQuery())) {
            dataSource.setValidationQuery(druidProperties.getValidationQuery());
        }
        if (Objects.nonNull(druidProperties.getTestWhileIdle())) {
            dataSource.setTestWhileIdle(druidProperties.getTestWhileIdle());
        }
        if (Objects.nonNull(druidProperties.getTestOnBorrow())) {
            dataSource.setTestOnBorrow(druidProperties.getTestOnBorrow());
        }
        if (Objects.nonNull(druidProperties.getTestOnReturn())) {
            dataSource.setTestOnReturn(druidProperties.getTestOnReturn());
        }
        if (Objects.nonNull(druidProperties.getPoolPreparedStatements())) {
            dataSource.setPoolPreparedStatements(druidProperties.getPoolPreparedStatements());
        }
        if (Objects.nonNull(druidProperties.getMaxPoolPreparedStatementPerConnectionSize())) {
            dataSource.setMaxPoolPreparedStatementPerConnectionSize(druidProperties
                    .getMaxPoolPreparedStatementPerConnectionSize());
        }
        if (Objects.nonNull(druidProperties.getConnectionProperties())) {
            dataSource.setConnectionProperties(druidProperties.getConnectionProperties());
        }
        //监控配置
        try {
            if (Objects.nonNull(druidProperties.getFilters())) {
                dataSource.setFilters(druidProperties.getFilters());
            }
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }
        return dataSource;
    }

    /**
     * 注册druid statViewServlet
     *
     * @return
     */
    @Bean
    @ConditionalOnExpression("'${tiangong.druid.filters}'.contains('stat')")
    public ServletRegistrationBean druidStatViewServlet() {
        ServletRegistrationBean statViewServlet =
                new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        DruidProperties druidProperties = tiangongProperties.getDruid();
        if (Objects.nonNull(druidProperties.getAdmin().getAllow())) {
            statViewServlet.addInitParameter("allow", druidProperties.getAdmin().getAllow());
        }
        if (Objects.nonNull(druidProperties.getAdmin().getDeny())) {
            statViewServlet.addInitParameter("deny", druidProperties.getAdmin().getDeny());
        }
        if (Objects.nonNull(druidProperties.getAdmin().getLoginUsername())) {
            statViewServlet.addInitParameter("loginUsername", druidProperties.getAdmin().getLoginUsername());
        }
        if (Objects.nonNull(druidProperties.getAdmin().getLoginPassword())) {
            statViewServlet.addInitParameter("loginPassword", druidProperties.getAdmin().getLoginPassword());
        }
        if (Objects.nonNull(druidProperties.getAdmin().getResetEnable())) {
            statViewServlet.addInitParameter("resetEnable", druidProperties.getAdmin().getResetEnable());
        }
        return statViewServlet;
    }

    @Bean
    @ConditionalOnExpression("'${tiangong.druid.filters}'.contains('stat')")
    public FilterRegistrationBean druidStatFilter() {
        FilterRegistrationBean druidStatFilter = new FilterRegistrationBean(new WebStatFilter());
        druidStatFilter.addUrlPatterns("/*");
        druidStatFilter.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return druidStatFilter;
    }

}
